package com.dmap.analysispoint.service.impl;

import com.dmap.analysispoint.bo.*;
import com.dmap.analysispoint.constants.BurialPointConstant;
import com.dmap.analysispoint.dao.*;
import com.dmap.analysispoint.po.*;
import com.dmap.analysispoint.service.BurialPointInfoAnalysisByDateService;
import com.dmap.analysispoint.service.GetCompanyIdService;
import com.dmap.analysispoint.utils.VersionUtils;
import com.dmap.base.units.DateUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * \* @author:zhouhao
 * \* Date:09/05/2018
 * \* Description:
 * \*
 */
@Service
public class BurialPointInfoAnalysisByDateServiceImpl implements BurialPointInfoAnalysisByDateService {

    @Resource
    private BurialPointMapper burialPointMapper;
    @Resource
    private BurialPointAllMapper burialPointAllMapper;
    @Resource
    private BurialPointAddUserMapper burialPointAddUserMapper;
    @Resource
    private BurialPointAddEquipmentMapper burialPointAddEquipmentMapper;
    @Resource
    private BurialPointAddPhoneMapper burialPointAddPhoneMapper;
    @Resource
    private BurialPointDayUserMapper burialPointDayUserMapper;
    @Resource
    private BurialPointDayPhoneMapper burialPointDayPhoneMapper;
    @Resource
    private BurialPointDayEquipmentMapper burialPointDayEquipmentMapper;
    @Resource
    private BurialPointHourUserMapper burialPointHourUserMapper;
    @Resource
    private BurialPointHourPhoneMapper burialPointHourPhoneMapper;
    @Resource
    private BurialPointHourEquipmentMapper burialPointHourEquipmentMapper;
    @Resource
    private BurialPointAppVersionMapper burialPointAppVersionMapper;
    @Resource
    private GetCompanyIdService getCompanyIdService;

    /**
     * @Description 将埋点信息表中数据转移到BurialPointAll表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer insertInfoToBurialPointAll(Long startTime, Long endTime) {
        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            List<BurialPoint> burialPointList = this.selectBurialPointInfoList(startTime, endTime, pageIndex, pageSize);
            if (!CollectionUtils.isEmpty(burialPointList)) {
                List<BurialPointAllBo> burialPointAllBoList = new ArrayList<>();
                burialPointList.forEach(burialPoint ->
                        burialPointAllBoList.add(new BurialPointAllBo(burialPoint))
                );
                int num = burialPointAllMapper.insertBatch(burialPointAllBoList);
                success = success + num;
                pageIndex++;
                burialPointAllBoList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    private List<BurialPoint> selectBurialPointInfoList(Long startTime, Long endTime, Integer pageIndex, Integer pageSize){
        if (startTime == null || endTime == null || endTime == 0) {
            return Collections.emptyList();
        }
        BurialPointExample example = new BurialPointExample();
        example.createCriteria().andLoginTimeBetween(startTime, endTime);
        example.setLimitStart((pageIndex - 1) * pageSize);
        example.setLimitEnd(pageSize);
        return burialPointMapper.selectByExample(example);
    }

    /**
     * @Description 将埋点信息表中新增帐号信息转移到BurialPointAddUser表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer insertInfoToBurialPointAddUser(Long startTime, Long endTime) {
        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            List<BurialPoint> burialPointList = this.selectGroupByUserIdBurialPointInfoList(startTime, endTime, pageIndex, pageSize);
            if (!CollectionUtils.isEmpty(burialPointList)) {
                List<BurialPointAddUserBo> burialPointAddUserBoList = new ArrayList<>();
                burialPointList.forEach(burialPoint ->
                    burialPointAddUserBoList.add(new BurialPointAddUserBo(burialPoint))
                );
                for (BurialPointAddUserBo burialPointAddUserBo : burialPointAddUserBoList) {
                    burialPointAddUserBo.setCompanyId(getCompanyIdService.getCompanyIdByProjectId(burialPointAddUserBo.getProjectId()));
                }
                int num = burialPointAddUserMapper.insertBatch(burialPointAddUserBoList);
                success = success + num;
                pageIndex++;
                burialPointAddUserBoList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    /**
     * @Description 将埋点信息表中数据按小时分析帐号信息转移到BurialPointHourUser表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer insertInfoToBurialPointHourUser(Long startTime, Long endTime) {
        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            List<BurialPoint> burialPointList = this.selectGroupByUserIdBurialPointInfoList(startTime, endTime, pageIndex, pageSize);
            if (!CollectionUtils.isEmpty(burialPointList)) {
                List<BurialPointSumStartUpNumUserTimeBo> sumStartUpNumUserTimeList = this.countStartUpNumUserTime(startTime, endTime, pageIndex, pageSize);
                List<BurialPointByUserBo> burialPointByUserBoHourList = new ArrayList<>();
                burialPointList.forEach(burialPoint ->
                        burialPointByUserBoHourList.add(new BurialPointByUserBo(burialPoint))
                );
                for (int i = 0; i < burialPointByUserBoHourList.size(); i++) {
                    BurialPointSumStartUpNumUserTimeBo burialPointSumStartUpNumUserTimeBo = sumStartUpNumUserTimeList.get(i);
                    BurialPointByUserBo burialPointByUserBo = burialPointByUserBoHourList.get(i);
                    burialPointByUserBo.setStartUpNum(burialPointSumStartUpNumUserTimeBo.getStartUpNum());
                    burialPointByUserBo.setUserTime(burialPointSumStartUpNumUserTimeBo.getUserTime());
                    burialPointByUserBo.setCompanyId(getCompanyIdService.getCompanyIdByProjectId(burialPointByUserBo.getProjectId()));
                }
                int num = burialPointHourUserMapper.insertBatch(burialPointByUserBoHourList);
                success = success + num;
                pageIndex++;
                burialPointByUserBoHourList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    /**
     * @Description 获取启动次数和使用时长
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 每个用户在查询时间段内启动次数总数和使用时长总数
     */
    private List<BurialPointSumStartUpNumUserTimeBo> countStartUpNumUserTime(Long startTime, Long endTime, Integer pageIndex, Integer pageSize) {
        if (startTime == null || endTime == null || endTime == 0) {
            return Collections.emptyList();
        }
        BurialPointExample example = new BurialPointExample();
        example.createCriteria().andLoginTimeBetween(startTime, endTime);
        example.setLimitStart((pageIndex - 1) * pageSize);
        example.setLimitEnd(pageSize);
        return burialPointMapper.selectSumStartUpNumUserTime(example);
    }

    private List<BurialPoint> selectGroupByUserIdBurialPointInfoList(Long startTime, Long endTime, Integer pageIndex, Integer pageSize){
        if (startTime == null || endTime == null || endTime == 0) {
            return Collections.emptyList();
        }
        BurialPointExample example = new BurialPointExample();
        BurialPointExample.Criteria criteria = example.createCriteria();
        criteria.andUserTypeEqualTo(0);
        criteria.andLoginTimeBetween(startTime, endTime);
        example.setLimitStart((pageIndex - 1) * pageSize);
        example.setLimitEnd(pageSize);
        return burialPointMapper.selectGroupByUserId(example);
    }

    /**
     * @Description 将埋点信息表中新增设备信息转移到BurialPointAddEquipment表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer insertInfoToBurialPointAddEquipment(Long startTime, Long endTime) {
        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            List<BurialPoint> burialPointList = this.selectGroupBySnBurialPointInfoList(startTime, endTime, pageIndex, pageSize);
            if (!CollectionUtils.isEmpty(burialPointList)) {
                List<BurialPointAddEquipmentBo> burialPointAddEquipmentBoList = new ArrayList<>();
                burialPointList.forEach(burialPoint ->
                        burialPointAddEquipmentBoList.add(new BurialPointAddEquipmentBo(burialPoint))
                );
                for (int i = 0; i < burialPointAddEquipmentBoList.size(); i++) {
                    BurialPointAddEquipmentBo burialPointAddEquipmentBo = burialPointAddEquipmentBoList.get(i);
                    if (!StringUtils.isBlank(burialPointAddEquipmentBo.getSn())) {
                        burialPointAddEquipmentBo.setCompanyId(getCompanyIdService.getCompanyIdByProjectId(burialPointAddEquipmentBo.getProjectId()));
                    }else {
                        burialPointAddEquipmentBoList.remove(i);
                        i--;
                    }
                }
                int num = burialPointAddEquipmentMapper.insertBatch(burialPointAddEquipmentBoList);
                success = success + num;
                pageIndex++;
                burialPointAddEquipmentBoList.clear();
                burialPointList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    /**
     * @Description 将埋点信息表中数据按小时分析设备信息转移到BurialPointHourEquipment表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer insertInfoToBurialPointHourEquipment(Long startTime, Long endTime) {
        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            List<BurialPoint> burialPointList = this.selectGroupBySnBurialPointInfoList(startTime, endTime, pageIndex, pageSize);
            if (!CollectionUtils.isEmpty(burialPointList)) {
                List<BurialPointByEquipmentBo> burialPointByEquipmentBoList = new ArrayList<>();
                burialPointList.forEach(burialPoint ->
                        burialPointByEquipmentBoList.add(new BurialPointByEquipmentBo(burialPoint))
                );
                for (int i = 0; i < burialPointByEquipmentBoList.size(); i++) {
                    BurialPointByEquipmentBo burialPointByEquipmentBo = burialPointByEquipmentBoList.get(i);
                    if (!StringUtils.isBlank(burialPointByEquipmentBo.getSn())) {
                    burialPointByEquipmentBo.setCompanyId(getCompanyIdService.getCompanyIdByProjectId(burialPointByEquipmentBo.getProjectId()));
                    }else {
                        burialPointByEquipmentBoList.remove(i);
                        i--;
                    }
                }
                int num = burialPointHourEquipmentMapper.insertBatch(burialPointByEquipmentBoList);
                success = success + num;
                pageIndex++;
                burialPointByEquipmentBoList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    private List<BurialPoint> selectGroupBySnBurialPointInfoList(Long startTime, Long endTime, Integer pageIndex, Integer pageSize){
        if (startTime == null || endTime == null || endTime == 0) {
            return Collections.emptyList();
        }
        BurialPointExample example = new BurialPointExample();
        example.createCriteria().andLoginTimeBetween(startTime, endTime);
        example.setLimitStart((pageIndex - 1) * pageSize);
        example.setLimitEnd(pageSize);
        return burialPointMapper.selectGroupBySn(example);
    }

    /**
     * @Description 将埋点信息表中新增手机信息转移到BurialPointAddPhone表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer insertInfoToBurialPointAddPhone(Long startTime, Long endTime) {
        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            List<BurialPoint> burialPointList = this.selectGroupByImeiBurialPointInfoList(startTime, endTime, pageIndex, pageSize);
            if (!CollectionUtils.isEmpty(burialPointList)) {
                List<BurialPointAddPhoneBo> burialPointAddPhoneBoList = new ArrayList<>();
                burialPointList.forEach(burialPoint ->
                        burialPointAddPhoneBoList.add(new BurialPointAddPhoneBo(burialPoint))
                );
                for (BurialPointAddPhoneBo burialPointAddPhoneBo : burialPointAddPhoneBoList) {
                    burialPointAddPhoneBo.setCompanyId(getCompanyIdService.getCompanyIdByProjectId(burialPointAddPhoneBo.getProjectId()));
                    burialPointAddPhoneBo.setSystemType(VersionUtils.setPhoneVersion(burialPointAddPhoneBo.getPhoneVersion()));
                }
                int num = burialPointAddPhoneMapper.insertBatch(burialPointAddPhoneBoList);
                success = success + num;
                pageIndex++;
                burialPointAddPhoneBoList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    /**
     * @Description 将埋点信息表中数据按小时分析手机信息转移到BurialPointHourPhone表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer insertInfoToBurialPointHourPhone(Long startTime, Long endTime) {
        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            List<BurialPoint> burialPointList = this.selectGroupByImeiBurialPointInfoList(startTime, endTime, pageIndex, pageSize);
            if (!CollectionUtils.isEmpty(burialPointList)) {
                List<BurialPointByPhoneBo> burialPointByPhoneBoList = new ArrayList<>();
                burialPointList.forEach(burialPoint ->
                        burialPointByPhoneBoList.add(new BurialPointByPhoneBo(burialPoint))
                );
                for (BurialPointByPhoneBo burialPointByPhoneBo : burialPointByPhoneBoList) {
                    burialPointByPhoneBo.setCompanyId(getCompanyIdService.getCompanyIdByProjectId(burialPointByPhoneBo.getProjectId()));
                }
                int num = burialPointHourPhoneMapper.insertBatch(burialPointByPhoneBoList);
                success = success + num;
                pageIndex++;
                burialPointByPhoneBoList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    private List<BurialPoint> selectGroupByImeiBurialPointInfoList(Long startTime, Long endTime, Integer pageIndex, Integer pageSize){
        if (startTime == null || endTime == null || endTime == 0) {
            return Collections.emptyList();
        }
        BurialPointExample example = new BurialPointExample();
        example.createCriteria().andLoginTimeBetween(startTime, endTime);
        example.setLimitStart((pageIndex - 1) * pageSize);
        example.setLimitEnd(pageSize);
        return burialPointMapper.selectGroupByImei(example);
    }

    /**
     * @Description 将埋点信息表中数据按天分析帐号信息转移到BurialPointDayUser表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer insertInfoToBurialPointDayUser(Long startTime, Long endTime) {
        if (startTime == null || endTime == null || endTime == 0) {
            return 0;
        }
        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            BurialPointHourUserExample example = new BurialPointHourUserExample();
            BurialPointHourUserExample.Criteria criteria = example.createCriteria();
            criteria.andLoginTimeBetween(startTime, endTime);
            example.setLimitStart((pageIndex - 1) * pageSize);
            example.setLimitEnd(pageSize);
            List<BurialPointHourUser> burialPointHourUserList = burialPointHourUserMapper.selectGroupByUserId(example);
            List<BurialPointSumStartUpNumUserTimeBo> sumStartUpNumUserTimeList = burialPointHourUserMapper.selectSumStartUpNumUserTime(example);
            if (!CollectionUtils.isEmpty(burialPointHourUserList)){
                for (int i = 0; i < burialPointHourUserList.size(); i++) {
                    BurialPointSumStartUpNumUserTimeBo burialPointSumStartUpNumUserTimeBo = sumStartUpNumUserTimeList.get(i);
                    BurialPointHourUser burialPointHourUser = burialPointHourUserList.get(i);
                    burialPointHourUser.setLoginTime(DateUtil.getDay0ByTime(burialPointHourUser.getLoginTime()));
                    burialPointHourUser.setStartUpNum(burialPointSumStartUpNumUserTimeBo.getStartUpNum());
                    burialPointHourUser.setUserTime(burialPointSumStartUpNumUserTimeBo.getUserTime());
                }
                int num = burialPointDayUserMapper.insertBatch(burialPointHourUserList);
                success = success + num;
                pageIndex++;
                burialPointHourUserList.clear();
                sumStartUpNumUserTimeList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    /**
     * @Description 将埋点信息表中数据按天分析手机信息转移到BurialPointDayPhone表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer insertInfoToBurialPointDayPhone(Long startTime, Long endTime) {
        if (startTime == null || endTime == null || endTime == 0) {
            return 0;
        }
        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            BurialPointHourPhoneExample example = new BurialPointHourPhoneExample();
            BurialPointHourPhoneExample.Criteria criteria = example.createCriteria();
            criteria.andLoginTimeBetween(startTime, endTime);
            example.setLimitStart((pageIndex - 1) * pageSize);
            example.setLimitEnd(pageSize);
            List<BurialPointHourPhone> burialPointHourPhoneList = burialPointHourPhoneMapper.selectGroupByImei(example);
            if (!CollectionUtils.isEmpty(burialPointHourPhoneList)){
                for (BurialPointHourPhone burialPointHourPhone : burialPointHourPhoneList) {
                    burialPointHourPhone.setLoginTime(DateUtil.getDay0ByTime(burialPointHourPhone.getLoginTime()));
                }
                int num = burialPointDayPhoneMapper.insertBatch(burialPointHourPhoneList);
                success = success + num;
                pageIndex++;
                burialPointHourPhoneList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    /**
     * @Description 将埋点信息表中数据按天分析设备信息转移到BurialPointDayEquipment表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    public Integer insertInfoToBurialPointDayEquipment(Long startTime, Long endTime) {
        if (startTime == null || endTime == null || endTime == 0) {
            return 0;
        }
        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            BurialPointHourEquipmentExample example = new BurialPointHourEquipmentExample();
            BurialPointHourEquipmentExample.Criteria criteria = example.createCriteria();
            criteria.andLoginTimeBetween(startTime, endTime);
            example.setLimitStart((pageIndex - 1) * pageSize);
            example.setLimitEnd(pageSize);
            List<BurialPointHourEquipment> burialPointHourEquipmentList = burialPointHourEquipmentMapper.selectGroupBySn(example);
            if (!CollectionUtils.isEmpty(burialPointHourEquipmentList)){
                for (BurialPointHourEquipment burialPointHourEquipment : burialPointHourEquipmentList) {
                    burialPointHourEquipment.setLoginTime(DateUtil.getDay0ByTime(burialPointHourEquipment.getLoginTime()));
                }
                int num = burialPointDayEquipmentMapper.insertBatch(burialPointHourEquipmentList);
                success = success + num;
                pageIndex++;
                burialPointHourEquipmentList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    /**
     * @Description 将埋点信息表中新增APP版本信息转移到BurialPointAppVersion表
     * @param  startTime;         开始时间
     *         endTime;           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer insertInfoToBurialPointAppVersion (Long startTime, Long endTime) {

        int pageIndex = 1;
        int pageSize = 1000;
        int success = 0;
        while (pageIndex > 0) {
            List<BurialPoint> burialPointList = this.selectBurialPointInfoList(startTime, endTime, pageIndex, pageSize);
            if (!CollectionUtils.isEmpty(burialPointList)) {
                List<BurialPointAppVersionInfoBo> burialPointAppVersionInfoBoList = new ArrayList<>();
                burialPointList.forEach(burialPoint ->
                        burialPointAppVersionInfoBoList.add(new BurialPointAppVersionInfoBo(burialPoint))
                );
                for (BurialPointAppVersionInfoBo burialPointAppVersionInfoBo : burialPointAppVersionInfoBoList) {
                    burialPointAppVersionInfoBo.setCompanyId(getCompanyIdService.getCompanyIdByProjectId(burialPointAppVersionInfoBo.getProjectId()));
                }
                int num = burialPointAppVersionMapper.insertBatch(burialPointAppVersionInfoBoList);
                success = success + num;
                pageIndex++;
                burialPointAppVersionInfoBoList.clear();
            }else {
                break;
            }
        }
        return success;
    }

    /**
     * @Description 将埋点信息表中处理过的数据进行删除
     * @param  startTime         开始时间
     *         endTime           结束时间
     *
     * @return 处理数据的条数
     */
    @Override
    @Transactional
    public Integer deleteInfoFromBurialPointByDate(Long startTime, Long endTime) {
        if (startTime == null || endTime == null || endTime == 0) {
            return 0;
        }
        BurialPointExample example = new BurialPointExample();
        example.createCriteria().andLoginTimeBetween(startTime, endTime);
        return burialPointMapper.deleteByExample(example);
    }
}
